package io.spring.demo.quotes;
import java.math.BigDecimal;
import java.math.MathContext;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.BiFunction;
import reactor.core.publisher.Flux;
import reactor.core.publisher.SynchronousSink;
import org.springframework.stereotype.Component;
@Component
public class QuoteGenerator {
private MathContext mathContext = new MathContext(2);
private Random random = new Random();
private List<Quote> prices = new ArrayList();
public QuoteGenerator() {
this.prices.add(new Quote("CTXS", 82.26));
this.prices.add(new Quote("DELL", 63.74));
this.prices.add(new Quote("GOOG", 847.24));
this.prices.add(new Quote("MSFT", 65.11));
this.prices.add(new Quote("ORCL", 45.71));
this.prices.add(new Quote("RHT", 84.29));
this.prices.add(new Quote("VMW", 92.21));
}
public Flux<Quote> fetchQuoteStream(Duration period) {
return Flux.generate(() -> 0,
(BiFunction<Integer, SynchronousSink<Quote>, Integer>) (index, sink) -> {
Quote updatedQuote = updateQuote(prices.get(index));
sink.next(updatedQuote);
return ++index % prices.size();
})
.zipWith(Flux.interval(period)).map(t -> t.getT1())
.map(quote -> {quote.setInstant(Instant.now()); return quote;})
.share()
.log();
}
private Quote updateQuote(Quote quote) {
BigDecimal priceChange = quote.getPrice()
.multiply(new BigDecimal(0.05 * this.random.nextDouble()), this.mathContext);
return new Quote(quote.getTicker(), quote.getPrice().add(priceChange));
}
}